package com.hwxm.ltim.service;

import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hwxm.ltim.dto.LoginRequest;
import com.hwxm.ltim.dto.LoginResponse;
import com.hwxm.ltim.dto.RegisterRequest;
import com.hwxm.ltim.dto.EmailRegisterRequest;
import com.hwxm.ltim.dto.BindEmailRequest;
import com.hwxm.ltim.dto.ResetPasswordRequest;
import com.hwxm.ltim.entity.User;
import com.hwxm.ltim.mapper.UserMapper;
import com.hwxm.ltim.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

/**
 * 用户服务
 */
@Slf4j
@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private EmailVerificationCodeService emailVerificationCodeService;

    /**
     * 用户注册
     */
    public User register(RegisterRequest request) {
        // 检查用户名是否已存在
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, request.getUsername());
        User existUser = userMapper.selectOne(wrapper);

        if (existUser != null) {
            throw new RuntimeException("用户名已存在");
        }

        // 创建新用户
        User user = new User();
        user.setUsername(request.getUsername());
        user.setPassword(DigestUtil.md5Hex(request.getPassword())); // MD5加密密码
        user.setNickname(request.getNickname());
        user.setPhone(request.getPhone());
        user.setEmail(request.getEmail());
        user.setStatus(1);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());

        userMapper.insert(user);
        log.info("用户注册成功：{}", user.getUsername());

        return user;
    }

    /**
     * 用户登录（支持用户名、手机号、邮箱）
     */
    public LoginResponse login(LoginRequest request) {
        // 查询用户（支持用户名、手机号、邮箱登录）
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, request.getUsername())
                .or()
                .eq(User::getPhone, request.getUsername())
                .or()
                .eq(User::getEmail, request.getUsername());
        User user = userMapper.selectOne(wrapper);

        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 验证密码
        String encryptedPassword = DigestUtil.md5Hex(request.getPassword());
        if (!encryptedPassword.equals(user.getPassword())) {
            throw new RuntimeException("密码错误");
        }

        // 检查用户状态
        if (user.getStatus() != 1) {
            throw new RuntimeException("用户已被禁用");
        }

        // 生成 token
        String token = jwtUtil.generateToken(user.getId());

        log.info("用户登录成功：{}", user.getUsername());

        return LoginResponse.builder()
                .userId(user.getId())
                .username(user.getUsername())
                .nickname(user.getNickname())
                .avatar(user.getAvatar())
                .token(token)
                .build();
    }

    /**
     * 根据ID获取用户信息
     */
    public User getUserById(Long userId) {
        User user = userMapper.selectById(userId);
        if (user != null) {
            user.setPassword(null); // 隐藏密码
        }
        return user;
    }

    /**
     * 搜索用户
     */
    public User searchUser(String keyword) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, keyword)
                .or()
                .eq(User::getPhone, keyword);
        User user = userMapper.selectOne(wrapper);
        if (user != null) {
            user.setPassword(null); // 隐藏密码
        }
        return user;
    }

    /**
     * 更新用户信息（仅允许更新昵称、头像、手机号、邮箱等基础资料）
     */
    public User updateUser(User incoming) {
        if (incoming == null || incoming.getId() == null) {
            throw new RuntimeException("用户ID不能为空");
        }

        User exist = userMapper.selectById(incoming.getId());
        if (exist == null) {
            throw new RuntimeException("用户不存在");
        }

        // 允许更新的字段（按需追加）
        if (incoming.getNickname() != null) {
            exist.setNickname(incoming.getNickname());
        }
        if (incoming.getAvatar() != null) {
            exist.setAvatar(incoming.getAvatar());
        }
        if (incoming.getPhone() != null) {
            exist.setPhone(incoming.getPhone());
        }
        if (incoming.getEmail() != null) {
            exist.setEmail(incoming.getEmail());
        }
        // 扩展字段：性别、个性签名
        try {
            // 性别通常是整型：0未知 1男 2女
            if (incoming.getGender() != null) {
                exist.setGender(incoming.getGender());
            }
        } catch (Exception ignore) {}
        if (incoming.getSignature() != null) {
            exist.setSignature(incoming.getSignature());
        }

        // 不允许在此接口修改：username、password、status 等敏感字段

        exist.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(exist);

        exist.setPassword(null);
        return exist;
    }

    /**
     * 修改密码
     */
    public void changePassword(Long userId, String oldPassword, String newPassword) {
        if (userId == null) {
            throw new RuntimeException("用户ID不能为空");
        }
        if (oldPassword == null || newPassword == null) {
            throw new RuntimeException("密码不能为空");
        }
        if (oldPassword.equals(newPassword)) {
            throw new RuntimeException("新密码不能与原密码相同");
        }

        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        String oldMd5 = DigestUtil.md5Hex(oldPassword);
        if (!oldMd5.equals(user.getPassword())) {
            throw new RuntimeException("原密码不正确");
        }

        user.setPassword(DigestUtil.md5Hex(newPassword));
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);
    }

    /**
     * 邮箱注册
     */
    public User emailRegister(EmailRegisterRequest request) {
        // 验证邮箱验证码
        if (!emailVerificationCodeService.verifyEmailRegister(request.getEmail(), request.getCode())) {
            throw new RuntimeException("邮箱验证码错误或已过期");
        }

        // 检查用户名是否已存在
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, request.getUsername());
        User existUser = userMapper.selectOne(wrapper);

        if (existUser != null) {
            throw new RuntimeException("用户名已存在");
        }

        // 检查邮箱是否已存在
        wrapper.clear();
        wrapper.eq(User::getEmail, request.getEmail());
        User existEmailUser = userMapper.selectOne(wrapper);

        if (existEmailUser != null) {
            throw new RuntimeException("邮箱已被注册");
        }

        // 创建新用户
        User user = new User();
        user.setUsername(request.getUsername());
        user.setPassword(DigestUtil.md5Hex(request.getPassword())); // MD5加密密码
        user.setNickname(request.getNickname());
        user.setPhone(request.getPhone());
        user.setEmail(request.getEmail());
        user.setStatus(1);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());

        userMapper.insert(user);
        log.info("用户邮箱注册成功：{}", user.getUsername());

        return user;
    }

    /**
     * 绑定邮箱
     */
    public void bindEmail(Long userId, BindEmailRequest request) {
        if (userId == null) {
            throw new RuntimeException("用户ID不能为空");
        }
        if (request.getEmail() == null || request.getCode() == null) {
            throw new RuntimeException("邮箱和验证码不能为空");
        }

        // 验证邮箱验证码
        if (!emailVerificationCodeService.verifyCode(request.getEmail(), request.getCode(), 4)) {
            throw new RuntimeException("邮箱验证码错误或已过期");
        }

        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 检查邮箱是否已被其他用户使用
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getEmail, request.getEmail())
                .ne(User::getId, userId);
        User existEmailUser = userMapper.selectOne(wrapper);

        if (existEmailUser != null) {
            throw new RuntimeException("该邮箱已被其他用户使用");
        }

        // 更新用户邮箱
        user.setEmail(request.getEmail());
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);

        log.info("用户{}绑定邮箱成功：{}", user.getUsername(), request.getEmail());
    }

    /**
     * 重置密码
     */
    public void resetPassword(ResetPasswordRequest request) {
        if (request.getAccount() == null || request.getCode() == null || request.getNewPassword() == null) {
            throw new RuntimeException("账号、验证码和新密码不能为空");
        }
        if (request.getMethod() == null) {
            throw new RuntimeException("重置方式不能为空");
        }

        // 验证重置方式
        if ("phone".equals(request.getMethod())) {
            // 手机号验证码验证（暂时不支持，需要实现短信验证码服务）
            throw new RuntimeException("手机号重置功能暂未实现，请使用邮箱重置");
        } else if (!"email".equals(request.getMethod())) {
            throw new RuntimeException("不支持的重置方式");
        }
        
        // 注意：验证码验证在步骤2中已经完成，这里不再重复验证

        // 查找用户
        User user = null;
        if ("phone".equals(request.getMethod())) {
            // 根据手机号查找用户
            LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(User::getPhone, request.getAccount());
            user = userMapper.selectOne(wrapper);
        } else if ("email".equals(request.getMethod())) {
            // 根据邮箱查找用户
            LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(User::getEmail, request.getAccount());
            user = userMapper.selectOne(wrapper);
        }

        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 更新密码
        user.setPassword(DigestUtil.md5Hex(request.getNewPassword()));
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);

        log.info("用户{}密码重置成功", user.getUsername());
    }
}

